'use strict';

/* Services */

angular.module('myApp.servicesGame', []).
        factory('serviceGame', ['$rootScope',
                                'serviceFirebaseUsers',
                                'serviceFirebaseGames',
        function($rootScope, firebaseUser, firebaseGame) {
                return {
                    playerUser: null,
                    ownerUser: null,
                    gameArray: null,
                    gameRef: null,
                    lastMove: null,
                    
                    value: null,
                    playerUserTmp: null,
                    lockedForValue: 0,
                    moveLocked: false,
                    
                    /**
                     * return all data from game, used in firebase db
                     */
                    getData: function() {
                        return {
                            playerUser: this.playerUser,
                            ownerUser: this.ownerUser,
                            gameArray: this.gameArray,
                            lastMove: this.lastMove,
                            lockedForValue: this.value
                        };
                    },
                    
                    setData: function(data) {
                        var flag = false;
                        if (typeof data.playerUser !== "undefined" && this.playerUser != data.playerUser) {
                            flag = true;
                        }

                        this.playerUser = data.playerUser;
                        this.ownerUser = data.ownerUser;
                        this.gameArray = data.gameArray;
                        this.lastMove = data.lastMove;
                        this.lockedForValue = data.lockedForValue;

                        if (flag) {
                            $rootScope.$apply();
                        }
                    },
                    
                    /**
                     * clear object
                     */
                    clear: function() {
                        this.playerUser = null;
                        this.ownerUser = null;
                        this.gameArray = null;
                        this.gameRef = null;
                        this.lastMove = null;
                        
                        this.value = null;
                        this.playerUserTmp = null;
                        this.lockedForValue = 0,
                        
                        this.moveLocked = false;
                        
                        console.log('game clear ', this);
                    },
                    
                    quit: function(callbackGameRemove) {
                        if (this.gameRef) {
                            //this.callbackGameRemove = callbackGameRemove;
                            console.log('game quit ', this);

                            var t = this;
                            t.gameRef.off('value');
                            t.gameRef.remove(function() {
                                t.clear();
                                callbackGameRemove();
                            });

                        } else {
                            this.clear();
                            callbackGameRemove();
                        }
                    },
                    
                    setWinner: function(winnerUser, callback) {
                        if (this.ownerUser && this.playerUser) {

                            var winner = null;
                            var loser = null;

                            if (this.ownerUser.email == winnerUser.email) {
                                var winner = this.ownerUser;
                                var loser = this.playerUser;
                            } else if (this.playerUser.email == winnerUser.email) {
                                var winner = this.playerUser;
                                var loser = this.ownerUser;
                            }

                            if (winner && loser) {
                                firebaseUser.setWinAndLose(winner, loser, callback);
                            } else {
                                callback();
                            }
                        } else {
                            callback();
                        }
                    },
                    
                    setLoser: function(loserUser, callback) {
                        if (this.ownerUser && this.playerUser) {

                            var winner = null;
                            var loser = null;

                            if (this.ownerUser.email == loserUser.email) {
                                var winner = this.playerUser;
                                var loser = this.ownerUser;
                            } else if (this.playerUser.email == loserUser.email) {
                                var winner = this.ownerUser;
                                var loser = this.playerUser;
                            }

                            if (winner && loser) {
                                firebaseUser.setWinAndLose(winner, loser, callback);
                            } else {
                                callback();
                            }
                        } else {
                            callback();
                        }
                    },
                    
                    createGame: function(elementCanvas, elementContainer, oponentLeftCallback, invitedSomeoneCallback) {
                        var t = this;
                        
                        // invitation staff
                        var initCallback = function () {};
                        var sendInvitiaionCallback = function () {};
                        if (t.playerUserTmp) {
                            initCallback = invitedSomeoneCallback;
                            sendInvitiaionCallback = function () {
                                firebaseUser.setUserInvitation(t.playerUserTmp, t.ownerUser, function() {
                                    console.log('user has been invited');
                                });
                            };
                        }
                        
                        // create tictactoe object
                        var tictactoe = new Tictactoe(elementCanvas, elementContainer, {value: t.value});
                        tictactoe.init(initCallback);
                                                
                        t.gameArray = tictactoe.getGame();
                        
                        // create game in firebase                        
                        firebaseGame.createGame(t.ownerUser, t.getData(), function(ref) {
                            // game has been created
                            console.log('game has ben created');

                            sendInvitiaionCallback();

                            // firebase.com
                            t.linkWithFirebase(ref, tictactoe, function() {
                                // your oponent has left so you win
                                t.quit(function() {
                                    oponentLeftCallback();
                                });
                            });
                        });
                    },
                    
                    joinGame: function(elementCanvas, elementContainer, oponentLeftCallback) {
                        var t = this;
                        
                        // create tictactoe object
                        var tictactoe = new Tictactoe(elementCanvas, elementContainer, {value: t.value});
                        tictactoe.init(function () {});
                        
                        t.gameArray = tictactoe.getGame();
                        
                        // create game in firebase                        
                        firebaseGame.joinGame(t.ownerUser, t.playerUser, function(ref) {
                            // game has been created
                            console.log('game has ben created');

                            // firebase.com
                            t.linkWithFirebase(ref, tictactoe, function() {
                                // your oponent has left so you win
                                t.quit(function() {
                                    oponentLeftCallback();
                                });
                            });
                        });
                    },
                    
                    /**
                     * link all elements together
                     */
                    linkWithFirebase: function(ref, tictactoe, callbackGameRemove) {
                        this.gameRef = ref;
                        
                        var t = this;

                        t.gameRef.on('value', function(snapshot) {
                            var val = snapshot.val();

                            if (val && val.loserUser) {
                                /**
                                 * oponent disconnected
                                 * point must be calculated from your side
                                 */
                                console.log('oponent disconnected');
                                t.setLoser(val.loserUser, callbackGameRemove);
                            } else if (val) {
                                /**
                                 * changes in game
                                 */
                                t.setData(val);
                                
                                /**
                                 * check if move is locked for this player
                                 * @todo : this block of code repeat bottom
                                 */
                                if (t.value == t.lockedForValue) {
                                    t.moveLocked = true;
                                } else {
                                    t.moveLocked = false;
                                }
                                if (t.lastMove) {
                                    tictactoe.setLastMove(t.lastMove.x, t.lastMove.y);
                                }
                                tictactoe.setMoveLocked(t.moveLocked);
                                tictactoe.setGame(t.gameArray);
                                
                                $rootScope.$apply();
                                
                                console.log('game changed in firebase db', t.getData());
                            } else {
                                /**
                                 * oponent left the game
                                 * point has been calculatet from his side
                                 */
                                console.log('oponent quit game purposely');
                                callbackGameRemove();
                            }
                        });

                        // handler of your move
                        tictactoe.setValueCallback = function(gameArrayAfterChange, x, y, value) {
                            t.gameArray = gameArrayAfterChange;
                            t.lastMove = { 'x' : x, 'y' : y};
                            
//                            /**
//                             * check if move is locked for this player
//                             * @todo : this block of code repeat top
//                             */
//                            t.moveLocked = true;
//                            
//                            tictactoe.setLastMove(x, y);
//                            tictactoe.setMoveLocked(t.moveLocked);
//                            $rootScope.$apply();
                            
                            t.gameRef.set(t.getData());
                            console.log('game changed in app',  t.getData());
                        };
                    }
                    
                }
            }]);
